package com.video.commons.loginaop;

import com.qf.entity.ResultData;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;

@Aspect
@Order(50)
@Component
public class LoginAOP {

    @Around("@annotation(MustLogin) && !@annotation(NoMustLogin)")
    public Object isLogin(ProceedingJoinPoint joinPoint) throws Throwable {

        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();
        HttpSession session = request.getSession();

        //获得方法的包
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();

        //获得方法的注解
        MustLogin annotation = method.getAnnotation(MustLogin.class);

        //判断是否登录
        Object loginUser = session.getAttribute(annotation.value().getKey());

        //发现未登录
        if (loginUser == null){
            //进行登录
            String header = request.getHeader("X-Requested-With");
            if(header != null && header.equals("XMLHttpRequest")){
                //说明当前是ajax请求
                //如果是ajax请求，出现异常应该返回json串
                return new ResultData<>().setCode(ResultData.ResultCodeList.NOLOGIN).setMsg("服务器登录失效，重新登录！").setData(annotation.value().getPath());
            } else {
                //说明当前是一个同步请求
                //如果是同步请求（表单提交、href...），出现异常应该返回错误页面
                return "redirect:" + annotation.value().getPath();
            }
        }

        //获得方法参数列表
        Parameter[] parameters = method.getParameters();
        Object[] args = joinPoint.getArgs();

        //循环所有参数
        for (int i = 0; i < args.length; i++) {
            if (parameters[i].isAnnotationPresent(LoginUser.class)){
                args[i] = loginUser;
            }
        }

        Object result = joinPoint.proceed(args);
        return result;
    }
}
